﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using BruteForceSerializer.Tests.TestClasses;
using ExpressionBuilder;
using NUnit.Framework;
using System.Linq;
using System.Linq.Expressions;

namespace BruteForceSerializer.Tests
{
    [TestFixture]
    public class test_Serializer
    {
		[SetUp]
		public void SetUp()
		{
			TypeResolve.Loader_Net45.AssemblyLoader.ConfigurePlatformBasedAssemblyLoading();
		}

		[Test]
		public void Integrationstest_Serialize()
		{
			var sut = new Serializer();

			var text = sut.Serialize(42);

			Assert.AreEqual(@"{""_Id"":0,""_Type"":""int"",""value"":42}", text);
		}

		[Test]
		public void Integrationstest_Deserialize()
		{
			var sut = new Serializer();

			var obj = sut.DeSerialize(@"{
  ""_Id"": 0,
  ""_Type"": ""int"",
  ""m_value"": 42
}");
			Assert.AreEqual(42, obj);
		}

    	[Test]
        public void Null_kann_serialisiert_werden() {
            var sut = new Serializer();

            var text = sut.Serialize(null);


            Assert.AreEqual("null", text);
        }

		[Test]
		public void Integrationstest_ComplexClass()
		{
			var sut = new Serializer();

			var obj = new KlasseMitCollections();
			string serialized = sut.Serialize(obj);
			//var bytes = Encoding.UTF8.GetBytes(serialized);
			Console.WriteLine(serialized);
			var obj2 = sut.DeSerialize(serialized);
			Assert.IsNotNull(obj2);
		}

		[Test]
		public void Integrationstest_ClassWithRefs()
		{
			var sut = new Serializer();

			var obj = new KlasseMitCollections();
			var info = new KlasseMitInfos();
			obj.ComplexList = new List<KlasseMitInfos> {info, info, new KlasseMitInfos()};
			string serialized = sut.Serialize(obj);
			Console.WriteLine(serialized);
			
			var obj2 = sut.DeSerialize(serialized) as KlasseMitCollections;
			Assert.IsNotNull(obj2);
			Assert.IsNotNull(obj2.ComplexList);
			Assert.AreEqual(3, obj2.ComplexList.Count);
			Assert.AreSame(obj2.ComplexList[0], obj2.ComplexList[1]);
		}

		[Test]
		public void Integrationstest_ClassWithByteArray()
		{
			var sut = new Serializer();

			var obj = new KlasseMitByteArray();
			obj.bytes = Enumerable.Range(0, 2550).Select(x => (byte) (x%255)).ToArray();

			string serialized = sut.Serialize(obj);
			Console.WriteLine(serialized);
			Console.WriteLine("Length: " + Encoding.UTF8.GetBytes(serialized).Length);


			var obj2 = sut.DeSerialize(serialized) as KlasseMitByteArray;
			Assert.IsNotNull(obj2);
			Assert.IsNotNull(obj2.bytes);
			Assert.AreEqual(obj.bytes, obj2.bytes);
		}

		[Test]
		public void Integrationstest_Expressions()
		{
			var sut = new Serializer();

			Expression<Predicate<string>> testexpr = (str => str.Length == 5 && str.Substring(0, 1) == "a");
			var obj = EditableExpression.CreateEditableExpression(testexpr);
			
			string serialized = sut.Serialize(obj);
			Console.WriteLine(serialized);
			Console.WriteLine("Length: " + Encoding.UTF8.GetBytes(serialized).Length);


			var obj2 = sut.DeSerialize(serialized) as EditableExpression;
			var resultExpr = (Expression<Predicate<string>>) obj2.ToExpression();
			var resultPredicate = resultExpr.Compile();
			
			Assert.IsNotNull(obj2);
			Assert.IsTrue(resultPredicate("a2345"));
			Assert.IsFalse(resultPredicate("12345"));
			Assert.IsFalse(resultPredicate("a234"));
		}
    }
}